package com.shenglue.ssi.action;

import java.io.ByteArrayInputStream;

import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.lang.reflect.Method;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;


import org.apache.commons.io.output.ByteArrayOutputStream;
import org.apache.poi.hssf.usermodel.HSSFCell;
import org.apache.poi.hssf.usermodel.HSSFRichTextString;
import org.apache.poi.hssf.usermodel.HSSFRow;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.struts2.ServletActionContext;

import com.opensymphony.xwork2.ActionContext;
import com.opensymphony.xwork2.ActionSupport;

import com.shenglue.ssi.domain.Exportable;

public class BaseAction extends ActionSupport {

	private static final long serialVersionUID = 1L;
	protected String errMsg;			// 错误消息  。曾想：一开始不为null，还带个空格，免得后面再判断，结果没用

	protected String fileName;  		// 传给 struts.xml中的 ${fileName}，是用于下载的Excel文件名
	private	  InputStream excelStream;  // 对应 struts.xml中的 那个excelStream，两者必须一致

	/**
	 * 进行 编码转换。因为是用于URL的
	 * @return
	 */
	public String getErrMsg() {  // 只有 getter
		if ( errMsg == null )
			errMsg = "";
		else {
			try {
				errMsg = java.net.URLEncoder.encode( errMsg, "utf-8" );
			} catch (UnsupportedEncodingException e) {
				errMsg = "";
				// 还应该 记日志
			}
		} // End of else

		return errMsg;
	}

	/**
	 * 传给 struts.xml中的 ${fileName}，是用于下载的Excel文件名，并进行中文文件名的转换
	 * @return String
	 */
	public String getFileName() {  // 只有 getter
		String exportFileName;
		try {
			exportFileName = new String( fileName.getBytes(), "ISO8859-1" );
		} catch ( UnsupportedEncodingException e ) {
			exportFileName = "QueryResult";
			e.printStackTrace();
		}
		return exportFileName;
		// return fileName;
	}

	public InputStream getExcelStream() {   // 只有 getter
		return excelStream;
	}



	// 将Workbook写入到InputStream
	protected void workbook2InputStream( HSSFWorkbook workbook,String fileName
	) throws Exception {

		ByteArrayOutputStream baos = new ByteArrayOutputStream();
		workbook.write( baos );
		baos.flush();
		byte[] aa = baos.toByteArray();
		excelStream = new ByteArrayInputStream(aa, 0, aa.length);
		baos.close();
	}

	// 将list转换为Excel工作表
	protected HSSFWorkbook getWorkbook( List<Exportable> list) throws Exception{
		HSSFWorkbook workbook = new HSSFWorkbook();
		HSSFSheet sheet = workbook.createSheet( "sheet1" );
		String[] columnNames;
		String[] columnMethods;


		// 首先，我们读取list中的第一个元素，根据它来确定工作表的列名，以及输出数据所对应的方法数组
		Exportable exp = list.get(0);
		columnNames	  = exp.getColumnTitles();
		columnMethods = exp.getColumnMethods();

		HSSFRow row = sheet.createRow(0); //创建第1行，也就是输出表头
		HSSFCell cell;
		for( int i=0; i< columnNames.length; i++ ) {
			cell = row.createCell(i); //创建第i列
			cell.setCellValue( new HSSFRichTextString(columnNames[i]) );
		}

		SimpleDateFormat dateFormater = new SimpleDateFormat( "yyyy-MM-dd" );
		//下面是输出各行的数据
		for (int i = 0; i < list.size(); i++) {
			exp = list.get(i);  // 用上 Exportable
			row = sheet.createRow( i+1 );//创建第i+1行
			for( int j=0; j<columnMethods.length; j++ ) {
				cell = row.createCell(j);//创建第j列
				Method method;
				method = exp.getClass().getMethod(columnMethods[j]);  //这里用到了反射机制，通过方法名来取得对应方法返回的结果对象
				Object objResult = method.invoke( exp );
				String str2Write;
				if ( objResult instanceof Date ) {
					str2Write = dateFormater.format( objResult );
				} else {
					str2Write = objResult.toString();
				}
				cell.setCellValue( str2Write );
			}
		}
		return workbook;
	}
}
